#local media assets agent
import os, string, hashlib, base64, re, plistlib, unicodedata
#import config
#import helpers
#import localmedia
#import audiohelpers
#import videohelpers


IMAGE_EXTS        = ['jpg', 'png', 'jpeg', 'tbn']
ART_EXTS          = ['jpg','jpeg','png','tbn']
AUDIO_EXTS        = ['mp3']
SUBTITLE_EXTS     = ['utf','utf8','utf-8','srt','smi','rt','ssa','aqt','jss','ass','idx','sub','txt', 'psb']
VIDEO_EXTS        = ['3gp', 'asf', 'asx', 'avc', 'avi', 'avs', 'bin', 'bivx', 'bup', 'divx', 'dv', 'dvr-ms', 'evo', 'fli', 'flv', 'ifo', 'img', 
                     'iso', 'm2t', 'm2ts', 'm2v', 'm4v', 'mkv', 'mov', 'mp4', 'mpeg', 'mpg', 'mts', 'nrg', 'nsv', 'nuv', 'ogm', 'ogv', 
                     'pva', 'qt', 'rm', 'rmvb', 'sdp', 'svq3', 'strm', 'ts', 'ty', 'vdr', 'viv', 'vob', 'vp3', 'wmv', 'wpl', 'xsp', 'xvid']

POSTER_FILES      = ['poster','default','cover','movie','folder']
ART_FILES         = ['fanart','art','background','backdrop']

PERSONAL_MEDIA_IDENTIFIER = "com.plexapp.agents.none"

#####################################################################################################################

#####################################################################################################################

def FindUniqueSubdirs(dirs):
  final_dirs = {}
  for dir in dirs:
    final_dirs[dir] = True
    try: 
      parent = os.path.split(dir)[0]
      final_dirs[parent] = True
      try: final_dirs[os.path.split(parent)[0]] = True
      except: pass
    except: pass
  if final_dirs.has_key(''):
    del final_dirs['']
  return final_dirs


def Start():
 Log('entrando en Start()')

class simplelMediaTV(Agent.TV_Shows):
  name = 'Simple Media (TV)'
  languages = [Locale.Language.NoLanguage]
  primary_provider = False
  persist_stored_files = False
  #contributes_to = ['com.plexapp.agents.thetvdb', 'com.plexapp.agents.none']

  def search(self, results, media, lang):
    Log('entra search')
    results.Append(MetadataSearchResult(id = 'null', score = 100))
    

  def update(self, metadata, media, lang):
    # Set title if needed.
    if media and metadata.title is None: metadata.title = media.title

    # Look for media, collect directories.
    dirs = {}
    for s in media.seasons:
      Log('Creating season %s', s)
      metadata.seasons[s].index = int(s)
      for e in media.seasons[s].episodes:
        
        # Make sure metadata exists, and find sidecar media.
        episodeMetadata = metadata.seasons[s].episodes[e]
        episodeMedia = media.seasons[s].episodes[e].items[0]
        archivo = os.path.basename(media.seasons[s].episodes[e].items[0].parts[0].file)
        p = re.compile("(.*[sS]\d?\d\d[eE]\d?\d?\d\d[^a-z0-9]*)(.*)(\.[\w]{3}$)",re.IGNORECASE)
        m = p.match(archivo)
        episodeMetadata.title=m.groups()[1]
        Log("episodeMetadata.title %s",episodeMetadata.title)
        dir = os.path.dirname(episodeMedia.parts[0].file)
        dirs[dir] = True
        
        try: findAssests(episodeMetadata, [dir], 'episodio', episodeMedia.parts[0])
        except: Log("Error finding season media for episode")
        
    # Figure out the directories we should be looking in.
    try: dirs = FindUniqueSubdirs(dirs)
    except: dirs = []
    
    # Look for show images.
    Log("Looking for show media for %s.", metadata.title)
    try: findAssests(metadata, dirs, 'show')
    except: Log("Error finding show media.")
    
    # Look for season images.
    for s in metadata.seasons:
      Log('Looking for season media for %s season %s.', metadata.title, s)
      try: findAssests(metadata.seasons[s], dirs, 'season')
      except: Log(" Error finding season media for season %s" % s)


def findAssests(metadata, paths, type, part = None):
  root_file = getRootFile(unicodize(part.file)) if part else None
  Log('entra findAssest')
  # We start by building a dictionary of files to their absolute paths. We also need to know
  # the number of media files that are actually present, in case the found local media asset 
  # is limited to a single instance per media file.
  path_files = {}
  total_media_files = 0
  for path in paths:
    path = unicodize(path)
    for file_path in os.listdir(path):
      Log('file_path %s',file_path)
      # When using os.listdir with a unicode path, it will always return a string using the
      # NFD form. However, we internally are using the form NFC and therefore need to convert
      # it to allow correct regex / comparisons to be performed.
      file_path = unicodedata.normalize('NFC', file_path)
      if os.path.isfile(os.path.join(path, file_path)):
        path_files[file_path.lower()] = os.path.join(path, file_path)

      # If we've found an actual media file (not a trailer), we should record it.
      (root, ext) = os.path.splitext(file_path)
      if ext.lower()[1:] in VIDEO_EXTS and root.lower().endswith('-trailer') == False:
        total_media_files += 1

  Log('Looking for %s media (%s) in %d paths (root file: %s) with %d media files.', type, metadata.title, len(paths), root_file, total_media_files)
  Log('Paths: %s', ", ".join([ unicode(p) for p in paths ]))

  # Figure out what regexs to use.
  search_tuples = []
  if type == 'season':
    search_tuples += [['season-?%s[-a-z]?' % metadata.index, metadata.posters, IMAGE_EXTS, False]]
    search_tuples += [['season-?%s-banner[-a-z]?' % metadata.index, metadata.banners, IMAGE_EXTS, False]]
  elif type == 'show':
    search_tuples += [['(show|poster|folder)-?[0-9]?', metadata.posters, IMAGE_EXTS, False]]
    search_tuples += [['banner-?[0-9]?', metadata.banners, config.IMAGE_EXTS, False]]
    search_tuples += [['(fanart|art|background|backdrop)-?[0-9]?', metadata.art, IMAGE_EXTS, False]]
    search_tuples += [['theme-?[0-9]?', metadata.themes, config.AUDIO_EXTS, False]]
  elif type == 'episode':
    search_tuples += [[re.escape(root_file) + '(-|-thumb)?[0-9]?', metadata.thumbs, IMAGE_EXTS, False]]
  elif type == 'movie':
    search_tuples += [['(poster|default|cover|movie|folder|' + re.escape(root_file) + ')-?[0-9]?', metadata.posters, IMAGE_EXTS, True]]
    search_tuples += [['(fanart|art|background|backdrop|' + re.escape(root_file) + '-fanart' + ')-?[0-9]?', metadata.art, IMAGE_EXTS, True]]

  for (pattern, media_list, extensions, limited) in search_tuples:
    valid_keys = []
    
    sort_index = 1
    file_path_keys = sorted(path_files.keys(), key = lambda x: os.path.splitext(x)[0])
    for file_path in file_path_keys:
      for ext in extensions:
        if re.match('%s.%s' % (pattern, ext), file_path, re.IGNORECASE):

          # Use a pattern if it's unlimited, or if there's only one media file.
          if (limited and total_media_files == 1) or (not limited) or (file_path.find(root_file.lower()) == 0):

            # Read data and hash it.
            data = Core.storage.load(path_files[file_path])
            media_hash = hashlib.md5(data).hexdigest()
      
            # See if we need to add it.
            valid_keys.append(media_hash)
            if media_hash not in media_list:
              media_list[media_hash] = Proxy.Media(data, sort_order = sort_index)
              sort_index = sort_index + 1
              Log('  Local asset added: %s (%s)', path_files[file_path], media_hash)
          else:
            Log('Skipping file %s because there are %d media files.', file_path, total_media_files)
              
    Log('Found %d valid things for pattern %s (ext: %s)', len(valid_keys), pattern, str(extensions))
    media_list.validate_keys(valid_keys)

def getRootFile(filename):
  path = os.path.dirname(filename)
  if 'video_ts' == splitPath(path.lower())[-1]:
    path = '/'.join(splitPath(path)[:-1])
  basename = os.path.basename(filename)
  (root_file, ext) = os.path.splitext(basename)
  return root_file
  
  
  # A platform independent way to split paths which might come in with different separators.
def splitPath(str):
  if str.find('\\') != -1:
    return str.split('\\')
  else: 
    return str.split('/')

def unicodize(s):
  filename = s
  try: filename = unicode(s.decode('utf-8'))
  except: pass
  return filename

def cleanFilename(filename):
  #this will remove any whitespace and punctuation chars and replace them with spaces, strip and return as lowercase
  return string.translate(filename.encode('utf-8'), string.maketrans(string.punctuation + string.whitespace, ' ' * len (string.punctuation + string.whitespace))).strip().lower()